home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / _udivmod.s < prev    next >
Text File  |  1990-04-03  |  2KB  |  76 lines

  1. | unsigned long division and modulus routines
  2. |
  3. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. |
  5. |
  6. | Revision 1.1, kub 03-90
  7. | first version, replaces the appropriate routine from fixnum.s.
  8. | Should be faster in more common cases. Division is done by 68000 divu
  9. | operations if divisor is only 16 bits wide. Otherwise the normal division
  10. | algorithm as described in various papers takes place. The division routine
  11. | delivers the quotient in d0 and the remainder in d1, thus the implementation
  12. | of the modulo operation is trivial.
  13.  
  14.     .text
  15.     .even
  16.     .globl    __udivsi3, ___udivsi3
  17.     .globl    __umodsi3, ___umodsi3
  18.  
  19. __udivsi3:
  20. ___udivsi3:
  21.     movel    d2,a0        | save registers
  22.     movel    d3,a1
  23.     clrl    d0        | prepare result
  24.     movel    sp@(8),d2    | get divisor
  25.     beq    9f        | divisor = 0 causes a division trap
  26.     movel    sp@(4),d1    | get dividend
  27. |== case 1) divident < divisor
  28.     cmpl    d2,d1        | is divident smaller then divisor ?
  29.     bcs    8f        | yes, return immediately
  30. |== case 2) divisor has <= 16 significant bits
  31.     tstw    sp@(8)
  32.     bne    2f        | divisor has only 16 bits
  33.     movew    d1,d3        | save dividend
  34.     clrw    d1        | divide dvd.h by dvs
  35.     swap    d1
  36.     beq    0f        | (no division necessary if dividend zero)
  37.     divu    d2,d1
  38. 0:    movew    d1,d0        | save quotient.h
  39.     swap    d0
  40.     movew    d3,d1        | (d1.h = remainder of prev divu)
  41.     divu    d2,d1        | divide dvd.l by dvs
  42.     movew    d1,d0        | save quotient.l
  43.     clrw    d1        | get remainder
  44.     swap    d1
  45.     bra    8f        | and return
  46. |== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
  47. 2:
  48.     moveq    #31,d3        | loop count
  49. 3:
  50.     addl    d1,d1        | shift divident ...
  51.     addxl    d0,d0        |  ... into d0
  52.     cmpl    d2,d0        | compare with divisor
  53.     bcs    0f
  54.     subl    d2,d0        | big enough, subtract
  55.     addw    #1,d1        | and note bit in result
  56. 0:
  57.     dbra    d3,3b
  58.     exg    d0,d1        | put quotient and remainder in their registers
  59. 8:
  60.     movel    a1,d3
  61.     movel    a0,d2
  62.     rts
  63. 9:
  64.     divu    d2,d1        | cause division trap
  65.     bra    8b        | back to user
  66.  
  67.  
  68. __umodsi3:
  69. ___umodsi3:
  70.     movel    sp@(8),sp@-    | push divisor
  71.     movel    sp@(8),sp@-    | push dividend
  72.     jbsr    __udivsi3
  73.     addql    #8,sp
  74.     movel    d1,d0        | return the remainder in d0
  75.     rts
  76.